import { Graph, Shape } from '@antv/x6';
import { showPorts } from './utils';
// 对节点进行旋转，缩放操作插件
import { Transform } from '@antv/x6-plugin-transform';
// 历史操作记录插件
import { History } from '@antv/x6-plugin-history';
// 操作提示线
import { Snapline } from '@antv/x6-plugin-snapline';
// 剪切板操作
import { Clipboard } from '@antv/x6-plugin-clipboard';
// 快捷键操作
import { Keyboard } from '@antv/x6-plugin-keyboard';
// 选择框操作
import { Selection } from '@antv/x6-plugin-selection';
// 拓扑信息导出操作
import { Export } from '@antv/x6-plugin-export';
// 提供画布滚动
import { Scroller } from '@antv/x6-plugin-scroller';
// 注册监听事件
import { graphLister } from './initLister';
// 左边拖拽栏
import { Stencil } from '@antv/x6-plugin-stencil';
import { MiniMap } from '@antv/x6-plugin-minimap';
// 随机生成ID
import { nanoid } from 'nanoid';
// 连接桩配置
import { ports } from './config';
import RegisterNode, {
  showContext,
} from './vueService';
// RegisterNode();

import {
  setSizeByTopo,
  setHTMLSizeHeightEcharts,
  setHTMLSize,
} from '@/utils/rem';
import { nextTick, ref } from 'vue';
import { v4 as uuidv4 } from 'uuid';

const isLightTheme = ref(false);
/**
 * @description 初始化 graph
 * @param {HTMLElement} targetRef
 * @returns
 */
export const initGraph = targetRef => {
  // 从拓扑设计右键到场景，默认是关闭
  showContext(false);

  // eslint-disable-next-line no-unused-vars
  const graph = new Graph({
    container: targetRef,
    highlighting: true, // 拖动边时，是否高亮显示所有可用的连接桩或节点
    // // connectionPoint: 'anchor', // 指定连接点
    // // anchor: 'midSide', // 指定被连接的节点的锚点
    // panning: {
    //   enabled: true,
    //   // modifiers: 'shift',
    // },
    connecting: {
      allowMulti: true, // 是否允许在相同的起始节点和终止之间创建多条边
      allowNode: true,
      allowBlank: false,
      allowLoop: false,
      snap: {
        radius: 20,
      },
      // router: 'orth',
      // router: 'oneSide',
      router: 'manhattan',
      connector: {
        // type: 'jumpover',
        args: {
          radius: 8,
        },
      },
      // anchor: 'center',
      connectionPoint: 'boundary',
      highlight: false,
      createEdge() {
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: '#7a7979',
              strokeWidth: 2,
              targetMarker: {
                name: 'block',
                width: 15,
                height: 10,
              },
            },
          },
          zIndex: 0,
        });
      },
      validateConnection({ targetCell, targetMagnet }) {
        showPorts(targetCell, true);
        return !!targetMagnet;
      },
    },
    scaling: {
      min: 0.3, // 默认值为 0.01
      max: 6, // 默认值为 16
    },
    // 鼠标缩放
    mousewheel: {
      enabled: true,
      modifiers: ['ctrl', 'meta'],
      zoomAtMousePosition: true,
      // minScale: 0.5,
      // maxScale: 3,
    },
    // 启用虚拟渲染
    virtual: true,
    // 虚拟渲染的配置
    virtualThreshold: 100, // 当节点数量超过 100 时启用虚拟渲染
    // 开启WebGL渲染
    renderer: 'webgl',
    // 开启异步渲染
    async: true,
    background: {
      color: '#ffffff',
    },
    // 优化渲染
    rendering: {
      optimize: true,
      // 限制重绘区域
      restrict: true,
    },
    grid: {
      visible: true,
      type: 'doubleMesh',
      args: [
        {
          color: '#eee', // 主网格线颜色
          thickness: 2, // 主网格线宽度
        },
        {
          color: '#ddd', // 次网格线颜色
          thickness: 2, // 次网格线宽度
          factor: 4, // 主次网格线间隔
        },
      ],
    },
    autoResize: true,
  });
  // graph.use(new Scroller({
  //   enabled: false,
  //   modifiers: ['alt', 'ctrl', 'shift', 'meta'],
  // }))
  graph.use(
    new Transform({
      rotating: true,
      resizing: {
        enabled: true,
        // minWidth: 1,
        // maxWidth: 200,
        // minHeight: 1,
        // maxHeight: 150,
        orthogonal: false,
        restrict: false,
        preserveAspectRatio: false,
      },
    }),
  );
  graph.use(
    new History({
      stackSize: 5,
      beforeAddCommand(arg, changeCell) {
        const flg =
          changeCell?.key === 'ports' ||
          changeCell?.key === 'tools' ||
          changeCell?.key != 'position';
        return !flg;
      },
      afterAddCommand(event, args, cmd) {
        return true;
      },
    }),
  );
  graph.use(new Snapline({ enabled: true }));
  graph.use(new Clipboard({ enabled: true }));
  graph.use(new Keyboard({ enabled: true }));
  graph.use(
    new Selection({
      multiple: true,
      movable: true,
      rubberband: true,
      showNodeSelectionBox: true,
      // showEdgeSelectionBox:true,
      pointerEvents: 'none',
      multipleSelectionModifiers: ['alt', 'ctrl', 'shift', 'meta'],
      modifiers: ['alt', 'ctrl', 'shift', 'meta'],
      eventTypes: ['leftMouseDown', 'mouseWheelDown', 'rightMouseDown'],
    }),
  );
  graph.use(new Export());
  graph.use(
    new Scroller({
      enabled: true,
      pageVisible: true,
      pageBreak: false,
      pannable: true,
    }),
  );
  if (document.querySelectorAll('#minimap .x6-widget-minimap').length === 0) {
    graph.use(
      new MiniMap({
        width: 200,
        height: 160,
        padding: 10,
        container: document.getElementById('minimap'),
      }),
    );
  }
  graphLister(graph, targetRef);

  return graph;
};

/**
 * @description 初始化 右侧Dnd组件拖拽栏
 * @param {Object} graph
 * @param {Object} groups
 * @param {Number} columns
 * @returns
 */
export const initStencil = (graph, groups, columns = 3) => {
  return new Stencil({
    title: '查询',
    target: graph,
    search(cell, keyword) {
      const {
        text: { text: _text },
      } = cell.getAttrs();

      nextTick(() => {
        // 搜索为空的时候
        if (!keyword) {
          const unmatchedArr = document.querySelectorAll(
            '.x6-widget-stencil-content .x6-widget-stencil-group',
          );
          unmatchedArr.forEach(item => {
            item.className = 'x6-widget-stencil-group collapsable';
          });
        }
      });

      if (!_text) return true;

      return _text.includes(keyword);
    },
    placeholder: '请输入组件名称',
    notFoundText: '暂时没有该组件',
    collapsable: true,
    layoutOptions: {
      columns: columns,
      columnWidth: setSizeByTopo(92),
      dx: setHTMLSizeHeightEcharts(10),
      dy: setHTMLSizeHeightEcharts(10), // 模板画布宽度
    },
    // stencilGraphWidth: 350,
    stencilGraphHeight: 0,
    groups,
  });
};

/**
 * @description 对目标节点进行数据格式化
 * @param {Array} arr
 * @returns
 */
export const initNode = arr => {
  isLightTheme.value = sessionStorage.getItem('themeMode') !== 'theme-blue';
  const env = import.meta.env.MODE;
  if (arr?.length) {
    const origin =
      env === 'development' ? 'http://172.16.1.150' : window.location.origin;
    return arr.map(el => {
      let tmpNode = [];
      const _list = el?.fileList;
      if (_list.length) {
        tmpNode = _list.map(_el => {
          return {
            id: uuidv4(),
            shape: 'org-node',
            x: 340,
            y: 10,
            width: 45,
            height: 54,
            attrs: {
              text: {
                text: _el.name,
                fontSize: 12,
                textWrap: {
                  text: _el.name,
                  width: 1,
                  ellipsis: true, // 文本超出显示范围时，自动添加省略号
                  breakWord: true,
                },
              },
              image: {
                'xlink:href': _el.path.startsWith('/')
                  ? _el.path
                  : '/' + _el.path, // 兼容之前未以/录入数据
                options: _el.options,
              },
              '.rank': {
                fill: 'transparent',
              },
              '.image': {
                refHeight2: '90%',
                refWidth2: '90%',
                refX: '20%',
                refY: '25%',
                x: 0,
                xAlign: 'middle',
                y: -7,
                yAlign: 'middle',
              },
              '.name': {
                fill: isLightTheme.value ? '#5b6775' : '#fff',
                fontFamily: 'Arial',
                refX: '20%',
                refY: '70%',
                xAlign: 'middle',
                yAlign: 'top',
                fontSize: 12,
                textWrap: {
                  width: setHTMLSizeHeightEcharts(66),
                },
                textVerticalAnchor: 'middle',
              },
              '.rankCenter': {
                fill: '#ff0000',
                height: 20,
                width: 20,
                xAlign: 'middle',
                refX: '50%',
                yAlign: 'top',
                refY: '0%',
                'xlink:href': ``,
              },
            },
            ports,
          };
        });
      }
      return {
        list: tmpNode,
        groupName: el.name,
      };
    });
  }
  return [];
};
